package hikari.gui.panels;

import com.gooddies.events.ValueChangedEvent;
import com.gooddies.texteditors.DefaultFloatTextField;
import com.gooddies.texteditors.DefaultTextField;
import com.gooddies.wiring.annotations.PostWiring;
import com.gooddies.wiring.annotations.Wire;
import com.gooddies.wiring.annotations.WiringComponent;
import hikari.gui.guicomponents.ExpandablePanel;
import hikari.gui.guicomponents.hLabel;
import hikari.objects3d.Basic3dObject;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import net.miginfocom.swing.MigLayout;
import org.swig.jirr.vector3df;

/**
 * @author sad
 */
@WiringComponent(singleton = true, lazy = true)
public class BasicObjectPropertiesPanel extends ExpandablePanel {

    private DefaultTextField objectName;
    private DefaultFloatTextField xPosition;
    private DefaultFloatTextField yPosition;
    private DefaultFloatTextField zPosition;
    private DefaultFloatTextField xRotation;
    private DefaultFloatTextField yRotation;
    private DefaultFloatTextField zRotation;
    private DefaultFloatTextField xScale;
    private DefaultFloatTextField yScale;
    private DefaultFloatTextField zScale;
    private Basic3dObject object;
    private boolean check = true;
    private JButton freezeButton;
    @Wire
    private HierarchyTree hierarchyTree;

    public enum UPDATE_TYPE {

        ALL, MOVE, ROTATE, SCALE
    };

    private BasicObjectPropertiesPanel() {        
    }

    @PostWiring
    private void init() {
        setTitle("Transformation");
        setLayout(new MigLayout("insets 5"));

        objectName = new DefaultTextField();
        objectName.setPreferredSize(new Dimension(200, 20));
        objectName.setValueChangedEvent(new ValueChangedEvent<String>() {
            @Override
            public void valueChanged(String value) {
                setNewObjectName(value);
            }
        });


        xPosition = createFloatTextField();
        yPosition = createFloatTextField();
        zPosition = createFloatTextField();

        xRotation = createFloatTextField();
        yRotation = createFloatTextField();
        zRotation = createFloatTextField();

        xScale = createFloatTextField();
        yScale = createFloatTextField();
        zScale = createFloatTextField();

        freezeButton = new JButton("Unfreeze");
        freezeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                freezeUnFreeze();
            }
        });

        add(new hLabel("Object name"), "span 10, wrap");
        add(objectName, "span 10, wrap");
        add(new hLabel("Position"), "span 10, wrap");
        add(new hLabel("X"));
        add(xPosition);
        add(new hLabel("Y"));
        add(yPosition);
        add(new hLabel("Z"));
        add(zPosition, "wrap");

        add(new hLabel("Rotation"), "span 10, wrap");
        add(new hLabel("X"));
        add(xRotation);
        add(new hLabel("Y"));
        add(yRotation);
        add(new hLabel("Z"));
        add(zRotation, "wrap");

        add(new hLabel("Scale"), "span 10, wrap");
        add(new hLabel("X"));
        add(xScale);
        add(new hLabel("Y"));
        add(yScale);
        add(new hLabel("Z"));
        add(zScale, "wrap");
        add(freezeButton, "span 10, wrap");
    }

    private void freezeUnFreeze() {
        object.freeze(!object.isFreezed());
        setFreezeButtonCaption(object.isFreezed());
    }

    private void setNewObjectName(String name) {
        object.setObjectName(name);
        hierarchyTree.refreshObject(object);

    }

    public void updatePanelData(UPDATE_TYPE type) {
        fillFields(object, type);
    }

    public void fillFields(Basic3dObject object, UPDATE_TYPE type) {
        check = false;
        this.object = object;
        objectName.setText(object.getObjectName());
        if (type == UPDATE_TYPE.ALL || type == UPDATE_TYPE.MOVE) {
            vector3df pos = object.getPosition();
            xPosition.setValue(pos.getX());
            yPosition.setValue(pos.getY());
            zPosition.setValue(pos.getZ());
        }

        if (type == UPDATE_TYPE.ALL || type == UPDATE_TYPE.ROTATE) {
            xRotation.setValue(object.getRotation().getX());
            yRotation.setValue(object.getRotation().getY());
            zRotation.setValue(object.getRotation().getZ());
        }

        if (type == UPDATE_TYPE.ALL || type == UPDATE_TYPE.SCALE) {
            xScale.setValue(object.getScaling().getX());
            yScale.setValue(object.getScaling().getY());
            zScale.setValue(object.getScaling().getZ());
        }
        check = true;
        setFreezeButtonCaption(object.isFreezed());
    }

    private void setFreezeButtonCaption(boolean isFreezed) {
        if (isFreezed) {
            freezeButton.setText("Unfreeze");
        } else {
            freezeButton.setText("Freeze");
        }
    }

    private void valueChanged(DefaultFloatTextField textField, double value) {
        if (!isExpanded()) {
            return;
        }
        if (!check) {
            return;
        }
        if (textField == xPosition) {
            object.setPositionWithUndo(object.getPosition().clone().setX((float) value));
        } else if (textField == yPosition) {
            object.setPositionWithUndo(object.getPosition().clone().setY((float) value));
        } else if (textField == zPosition) {
            object.setPositionWithUndo(object.getPosition().clone().setZ((float) value));
        } else if (textField == xRotation) {
            object.setRotationWithUndo(object.getRotation().clone().setX((float) value));
        } else if (textField == yRotation) {
            object.setRotationWithUndo(object.getRotation().clone().setY((float) value));
        } else if (textField == zRotation) {
            object.setRotationWithUndo(object.getRotation().clone().setZ((float) value));
        } else if (textField == xScale) {
            object.setScalingWithUndo(object.getScaling().clone().setX((float) value));
        } else if (textField == yScale) {
            object.setScalingWithUndo(object.getScaling().clone().setY((float) value));
        } else if (textField == zScale) {
            object.setScalingWithUndo(object.getScaling().clone().setZ((float) value));
        }
    }

    private DefaultFloatTextField createFloatTextField() {
        final DefaultFloatTextField field = new DefaultFloatTextField();
        field.setMinMax(-9999999, 9999999);
        field.setValueChangedEventNumber(new ValueChangedEvent<Float>() {
            @Override
            public void valueChanged(Float value) {
                BasicObjectPropertiesPanel.this.valueChanged(field, value);
            }
        });

        field.setAllowNegative(true);
        field.setPreferredSize(new Dimension(50, 20));
        return field;
    }
}
